package com.dotflat.rest.controller;

import com.dotflat.rest.PO.AreableObjectBasePO;
import com.dotflat.rest.domain.AreableObjectBase;
import com.dotflat.rest.service.AreableObjectBaseService;
import com.dotflat.rest.utils.ReadonlyField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.matt.commons.dto.sso.StaffDTO;
import com.matt.commons.exception.BusinessException;
import com.matt.commons.model.StatusResponse;
import com.matt.commons.page.PagerQuery;
import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.model.MemVerificationCache;
import com.matt.remoteCall.SsoCallService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.matt.foundation.constant.CommonConstant.TICKET;

public abstract class RestfulBaseController<T1 extends AreableObjectBase, T2 extends AreableObjectBaseService<T1>, P extends AreableObjectBasePO> {

    protected T2 baseService;
    public void setBaseService(T2 service){
        this.baseService = service;
    }

    @Autowired
    protected MemVerificationCache cache;

    @Autowired
    protected SsoCallService ssoCallService;

    @ApiOperation(value = "获取列表")
    @GetMapping("/list")
    public StatusResponse getList(@RequestHeader(TICKET) String ticket, P param, PagerQuery pagerQuery){
        StaffDTO staff = cache.getStaff(ticket);

        Sort sort = null;

        Field[] fields = param.getClass().getDeclaredFields();
        if (fields != null && fields.length > 0){
            for (Field f: fields){
                if ("sort".equals(f.getName())){
                    sort = Sort.by("sort", "created").descending();
                    break;
                }
            }
        }
        if (sort == null){
            sort = Sort.by( "created").descending();
//            sort = Sort.by("created").descending();
        }

//        PageRequest pageRequest = PageRequest.of(pagerQuery.getPageNum(), pagerQuery.getPageSize(), sort);
        PageRequest pageRequest = PageRequest.of(pagerQuery.getPageNum(), pagerQuery.getPageSize(), sort);
        return StatusResponse.success( baseService.page(staff.getAreaId(), staff.getId(), param, pageRequest));
    }

    @ApiOperation(value = "增加一条记录")
    @PostMapping()
    public StatusResponse add(@RequestHeader(TICKET) String ticket, P param){
        StaffDTO staff = cache.getStaff(ticket);

        T1 ret = baseService.add(staff.getAreaId(), staff.getId(), param);

        List<T1> tmp = new ArrayList<>();
        tmp.add(ret);

        return StatusResponse.success(tmp);
    }


    @ApiOperation(value = "更新一条记录")
    @PostMapping("/update")
    public StatusResponse update(@RequestHeader(TICKET) String ticket, P param){

        StaffDTO staff = cache.getStaff(ticket);

        if (StringUtils.isBlank(param.getId()) || StringUtils.isBlank(param.getAreaId())){
            return StatusResponse.error(ErrorCode.PARAM_CAN_NOT_BLANK, "areaId, id 必填");
        }

        T1 ret = baseService.get(staff.getAreaId(), staff.getId(), param.getId());

        if (ret == null){
            return StatusResponse.error(ErrorCode.PARAM_CAN_NOT_BLANK, "对象不存在");
        }

//        ret.setAudited(param.getAudited());
//        ret.setAuditContent(param.getAuditContent());

        ret = baseService.update(ret);

        return StatusResponse.success(ret);
    }

    @ApiOperation(value = "存档一条记录")
    @PostMapping("/archive")
    public StatusResponse archive(@RequestHeader(TICKET) String ticket,
                                String id, Integer archived
    ){

        StaffDTO staff = cache.getStaff(ticket);

        if (StringUtils.isBlank(id)){
            return StatusResponse.error(ErrorCode.PARAM_CAN_NOT_BLANK, "id 必填");
        }

        if (archived != 0 && archived != 1){
            return StatusResponse.error(ErrorCode.PARAM_CAN_NOT_BLANK, "归档状态不对");
        }

        T1 ret = baseService.get(staff.getAreaId(), staff.getId(), id);

        if (ret == null){
            return StatusResponse.error(ErrorCode.PARAM_CAN_NOT_BLANK, "对象不存在");
        }

        ret.setArchived(archived);

        ret = baseService.update(ret);

        return StatusResponse.success(ret);
    }

    @ApiOperation(value = "审核一条记录")
    @PostMapping("/audit")
    public StatusResponse audit(@RequestHeader(TICKET) String ticket,
                                String id, Integer audited, @RequestParam(required = false) String auditContent
    ){

        boolean permited = ssoCallService.checkStaffPermission(ticket, new String[]{"finance::audit::all"});

        if (!permited){
            return StatusResponse.error(ErrorCode.ROLE_NOT_EXIST, "权限错误");
        }

        StaffDTO staff = cache.getStaff(ticket);


        if (StringUtils.isBlank(id)){
            return StatusResponse.error(ErrorCode.PARAM_CAN_NOT_BLANK, "id 必填");
        }

        if (audited != 1 && audited != 2){
            return StatusResponse.error(ErrorCode.PARAM_CAN_NOT_BLANK, "审核状态不对");
        }

        T1 ret = baseService.get(staff.getAreaId(), staff.getId(), id);

        if (ret == null){
            return StatusResponse.error(ErrorCode.PARAM_CAN_NOT_BLANK, "对象不存在");
        }

        ret.setAudited(audited);

        ret = baseService.update(ret);

        return StatusResponse.success(ret);
    }

    @ApiOperation(value = "获取一个对象")
    @GetMapping()
    public StatusResponse get(@RequestHeader(TICKET) String ticket, String id){
        StaffDTO staff = cache.getStaff(ticket);
        return StatusResponse.success(baseService.get(staff.getAreaId(), staff.getId(), id));
    }

    @ApiOperation(value = "逻辑删除一个或多个对象")
    @DeleteMapping()
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", name = "ticket", value = "票据", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "formData", name = "ids", value = "对象id数组", required = false, dataType = "string[]"),
            @ApiImplicitParam(paramType = "formData", name = "id", value = "对象id， 和ids二选一", required = false, dataType = "string")
    })
    public StatusResponse delete(@RequestHeader(TICKET) String ticket, String[] ids, String id ){
        StaffDTO staff = cache.getStaff(ticket);

        if (StringUtils.isNotEmpty(id)) {
            AreableObjectBasePO param = new AreableObjectBasePO();
            param.setId(id);

            baseService.delete(staff.getAreaId(), staff.getId(), param);
        }else if(ids != null && ids.length > 0){
            baseService.delete(staff.getAreaId(), staff.getId(), ids);
        }else{
            throw new BusinessException(ErrorCode.PARAM_CAN_NOT_BLANK, "参数错误!");
        }

        return StatusResponse.success();
    }

}
